﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using T.FAS.Runtime.Base.Dao;
using T.FAS.Runtime.Metadata.Entity.ScheduleJob;
using T.ServiceComponent.DAC.Service;
using T.ServiceComponent.DataAccessEx.Core;

namespace T.FAS.Runtime.ScheduleJob.Dao
{
    public class ScheduleTriggerELBDao : DaoService<ScheduleTrigger>, IScheduleTriggerDao
    {
        public const string MetaDataID = "ScheduleTrigger";
        public const string MetaDataName = "ScheduleTrigger元数据参数";
        public override string TableName => "FAS_ScheduleTrigger";
        private string RelatedTableName => "fas_schedulejobtriggerrelation";
        public override string IDColumnName => "ID";
        public override List<string> ExceptColumnName
            => DaoUtil.GetExceptionColumn<Metadata.Entity.ScheduleJob.ScheduleJobData>(
                new List<string>
                {
                    "MetaDataID",
                    "MetaDataCode",
                    "MetaDataName"
                }
            );

        public ScheduleTriggerELBDao() : base()
        {
            DBName = "TFAS";
        }
        public override ScheduleTrigger ConvertToObject(Dictionary<string, PropertyInfo> columns, DataRow row)
        {
            if (columns.ContainsKey("TriggerType"))
                columns.Remove("TriggerType");
            if (columns.ContainsKey("MisfirePolicy"))
                columns.Remove("MisfirePolicy");

            var data = base.ConvertToObject(columns, row);

            data.TriggerType = (TriggerType)Enum.Parse(typeof(TriggerType), Convert.ToString(row["TriggerType"]));
            data.MisfirePolicy = (MisfirePolicy)Enum.Parse(typeof(MisfirePolicy),Convert.ToString(row["MisfirePolicy"]));

            return data;
        }

        public override Dictionary<string, object> GetDataMapping(ScheduleTrigger data)
        {
            var mapping = base.GetDataMapping(data);
            mapping.Remove("TriggerType");
            mapping.Add("TriggerType", (int)data.TriggerType);
            mapping.Remove("MisfirePolicy");
            mapping.Add("MisfirePolicy",(int)data.MisfirePolicy);

            return mapping;
        }

        public int CheckUnique(Dictionary<string, string> filter)
        {
            throw new NotImplementedException();
        }

        public void DeleteScheduleTrigger(string triggerID)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// 根据计划任务ID删除触发器信息
        /// </summary>
        /// <param name="sJobID"></param>
        public void DeleteScheduleTriggerByScheduleJobID(string sJobID)
        {
            var paramter = DB.MakeInParam("@ScheduleJobID", TDbDataType.VarChar, sJobID);
            var delSql = "delete from {0} where id in (select ScheduleTriggerID from {1} where ScheduleJobID=@ScheduleJobID )";
            DB.ExecSqlStatement(string.Format(delSql,TableName,RelatedTableName),paramter);
            DB.ExecSqlStatement(string.Format("delete from {0} where ScheduleJobID = @ScheduleJobID",RelatedTableName),paramter);
        }

        public List<ScheduleTrigger> GetScheduleTriggerByFilter(Dictionary<string, string> filter)
        {
            throw new NotImplementedException();
        }

        public ScheduleTrigger GetScheduleTriggerByID(string triggerID)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// 根据任务ID获取触发器数据
        /// </summary>
        /// <param name="sJobID"></param>
        /// <returns></returns>
        public ScheduleTrigger GetScheduleTriggerByScheduleJobID(string sJobID)
        {
            var parameterList = new List<IDbDataParameter>()
            { 
                DB.MakeInParam("@ScheduleJobID",TDbDataType.VarChar,sJobID)
            };
            var getSql = "select trig.* from {0} rel left join {1} trig on trig.ID = rel.ScheduleTriggerID where rel.ScheduleJobID=@ScheduleJobID";
            var triggerDS = DB.ExecuteDataSet(string.Format(getSql, RelatedTableName,TableName), parameterList.ToArray());
            var trigger = new ScheduleTrigger();
            if (triggerDS != null && triggerDS.Tables != null && triggerDS.Tables.Count > 0 && triggerDS.Tables[0].Rows != null && triggerDS.Tables[0].Rows.Count > 0)
            {
                trigger = ConvertToScheduleTrigger(triggerDS.Tables[0].Rows[0]);
            }
            else
                trigger = null; 
            return trigger;
        }

        public void UpdateScheduleTrigger(ScheduleTrigger trigger)
        {
            throw new NotImplementedException();
        }

        public void AddScheduleTrigger(Metadata.Entity.ScheduleJob.ScheduleJob sJob,ScheduleTrigger trigger)
        {
            if (trigger != null)
            {
                base.Add(new List<object>() { trigger });
                //关系表更新
                List<IDbDataParameter> paramsList = new List<IDbDataParameter>();
                paramsList.Add(DB.MakeInParam("@ID",TDbDataType.VarChar,Guid.NewGuid().ToString()));
                paramsList.Add(DB.MakeInParam("@ScheduleJobID",TDbDataType.VarChar,sJob.ID));
                paramsList.Add(DB.MakeInParam("@ScheduleTriggerID", TDbDataType.VarChar, trigger.ID));
                paramsList.Add(DB.MakeInParam("@Creator",TDbDataType.VarChar,sJob.Creator));
                paramsList.Add(DB.MakeInParam("@CreateTime",TDbDataType.DateTime,sJob.CreateTime));
                paramsList.Add(DB.MakeInParam("@LastModifier",TDbDataType.VarChar,sJob.LastModifier));
                paramsList.Add(DB.MakeInParam("@LastModifyTime",TDbDataType.DateTime,sJob.LastModifyTime)) ;


                var insertSql = "insert into {0} (ID,ScheduleJobID,ScheduleTriggerID,SortOrder,IsEnable,Creator,CreateTime,LastModifier,LastModifyTime) values" +
                    "(@ID,@ScheduleJobID,@ScheduleTriggerID,0,'1',@Creator,@CreateTime,@LastModifier,@LastModifyTime)";
                DB.ExecSqlStatement(string.Format(insertSql,RelatedTableName),paramsList.ToArray()); ;
            }
        }

        #region 私有方法
        private ScheduleTrigger ConvertToScheduleTrigger(DataRow row)
        {
            if (row != null)
            {
                return new ScheduleTrigger()
                {
                    ID = Convert.ToString(row["ID"]),
                    Code = Convert.ToString(row["Code"]),
                    Name = Convert.ToString(row["Name"]),
                    Description = Convert.ToString(row["Description"]),
                    TriggerGroup = Convert.ToString(row["TriggerGroup"]),
                    TriggerType = (TriggerType)Convert.ToInt16(row["TriggerType"]),
                    RepeatCount = Convert.ToInt16(row["RepeatCount"]),
                    RepeatInterval = Convert.ToInt16(row["RepeatInterval"]),
                    Priority = Convert.ToInt16(row["Priority"]),
                    MisfirePolicy =(MisfirePolicy)Convert.ToInt16(row["MisfirePolicy"]),
                    CronExpression = Convert.ToString(row["CronExpression"]),
                    EffectiveTime = Convert.ToDateTime(row["EffectiveTime"]),
                    ExecuteTime = Convert.ToDateTime(row["ExecuteTime"]),
                    ExpiredTime = Convert.ToDateTime(row["ExpiredTime"]),
                    IsSysDefault = Convert.ToInt16(row["IsSysDefault"]).Equals(1),
                    DelayTime = Convert.ToInt16(row["DelayTime"]),
                    TenantID = Convert.ToString(row["TenantID"]),
                    Ext1 = Convert.ToString(row["Ext1"]),
                    Ext2 = Convert.ToString(row["Ext2"]),
                    Ext3 = Convert.ToString(row["Ext3"]),
                    Creator = Convert.ToString(row["Creator"]),
                    CreateTime = Convert.ToDateTime(row["CreateTime"]),
                    LastModifier = Convert.ToString(row["LastModifier"]),
                    LastModifyTime = Convert.ToDateTime(row["LastModifyTime"]),
                };
            }
            return null;
        }
        #endregion
    }
}
